package com.kasa.zto;

import java.lang.reflect.Field;
import java.sql.Time;
import java.util.Date;

/**
 * <p>Title: </p>
 *
 * <p>Description: </p>
 *
 * <p>Copyright: Copyright (c) 2008</p>
 *
 * <p>Company: </p>
 *
 * @author not attributable
 * @version 1.0
 */
public class ZTOAny implements ZTOType
{
    private static final long serialVersionUID = -8579316139440362658L;

    public Object data;

    public ZTOAny()
    {
    }

    public void encode(ZTOEncoder encoder) throws ZTOException
    {
        if (null == data)
        {
            encoder.encode_byte(ZTOTag.NULL);
        }
        else if (data instanceof Boolean)
        {
            encoder.encode_byte(ZTOTag.BOOLEAN);
            encoder.encodeBoolean((Boolean) data);
        }
        else if (data instanceof Integer)
        {
            encoder.encode_byte(ZTOTag.Integer);
            encoder.encodeInteger((Integer) data);
        }
        else if (data instanceof Long)
        {
            encoder.encode_byte(ZTOTag.Long);
            encoder.encodeLong((Long) data);
        }
        else if (data instanceof Float)
        {
            encoder.encode_byte(ZTOTag.Float);
            encoder.encodeFloat((Float) data);
        }
        else if (data instanceof Double)
        {
            encoder.encode_byte(ZTOTag.Double);
            encoder.encodeDouble((Double) data);
        }
        else if (data instanceof String)
        {
            encoder.encode_byte(ZTOTag.String);
            encoder.encodeString((String) data);
        }
        else if (data instanceof Time) //time必须放在date前
        {
            encoder.encode_byte(ZTOTag.Time);
            encoder.encodeLong(((Time) data).getTime());
        }
        else if (data instanceof Date)
        {
            encoder.encode_byte(ZTOTag.Date);
            encoder.encodeLong(((Date) data).getTime());
        }
        else
        {
            throw new ZTOException("data is unknow type!");
        }
    }

    public void decode(ZTODecoder decoder) throws ZTOException
    {
        byte tag = decoder.decode_byte();
        switch (tag)
        {
            case ZTOTag.NULL:
            {
                break;
            }
            case ZTOTag.BOOLEAN:
            {
                data = decoder.decodeBoolean();
                break;
            }
            case ZTOTag.Integer:
            {
                data = decoder.decodeInteger();
                break;
            }
            case ZTOTag.Long:
            {
                data = decoder.decodeLong();
                break;
            }
            case ZTOTag.Float:
            {
                data = decoder.decodeFloat();
                break;
            }
            case ZTOTag.Double:
            {
                data = decoder.decodeDouble();
                break;
            }
            case ZTOTag.String:
            {
                data = decoder.decodeString();
                break;
            }
            case ZTOTag.Time:
            {
                data = decoder.decodeTime();
                break;
            }
            case ZTOTag.Date:
            {
                data = decoder.decodeDate();
                break;
            }
            default:
            {
                throw new ZTOException("tag is unknow type: tag == " + tag);
            }
        }
    }

    public Object getData()
    {
        return data;
    }

    public void setData(Object data)
    {
        this.data = data;
    }

    public String toString()
    {
        StringBuilder sb = new StringBuilder("\n");
        Field[] fs = this.getClass().getFields();
        for (Field field : fs)
        {
            try
            {
                sb.append(field.getName()).append("(").append(field.getType().getSimpleName()).append(")").append(" = ").append(field.get(this)).append("\n");
            }
            catch (Exception ex)
            {
                ex.printStackTrace();
            }
        }

        return sb.toString();
//        return data;
    }
}
